10. Preventing Resource Leaks
Preventing Resource Leaks
In this section, you will:
- Describe common kinds of resource leaks and how they can happen.
- Use
try
/catch
/finally
to prevent resource leaks. - Apply try-with-resources and the
Closeable
interface to prevent resource leaks. - Prevent closing resources multiple times.
ND079 JPND C2 L02 A12 Preventing Resource Leaks
Why Should We Prevent Resource Leaks?
- Leaving files open wastes memory and other system resources.
- Most operating systems limit the number of files that can be open at one time, so, when you leave a file open after you're done using it, you're potentially depriving programs of the ability to open other files in the future.
- If you are using a buffered writer and forget to close it, the buffered writes might never actually be written to disk.
SOLUTION:
- To avoid wasting resources.
- The operating system limits the number of open files.
- To ensure the file has latest information.
try-catch-finally
Example
try-catch-finally
can be very useful for preventing resource leaks.
Writer writer;
try {
writer = Files.newBufferedWriter(Path.of("test"));
writer.write("Hello, world!");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The code in the finally
block is guaranteed to execute after the code in the try
block, even if the try
block returns a value or throws an exception. This code also has a catch
block, but that is optional.
try-with-resources
Example
try (Writer writer = Files.newBufferedWriter(Path.of("test"))) {
writer.write("Hello, world!");
} catch (IOException e) {
e.printStackTrace();
}
Java 7 introduced the try-with-resources
syntax. This new syntax allows you to initialize your resources in parenthesis right before the start of the try
block. Resources initialized in this way are guaranteed to be closed after the try
block finishes executing.
Although try-with-resources
has removed the need for the finally
block in a lot of modern Java code, there are still some use cases where the finally
block is useful.
By the way, you can initialize multiple resources in the same try
statement, like this:
// Copy the contents of "foo" to "bar"
try (InputStream in = Files.newInputStream(Path.of("foo"));
OutputStream out = Files.newOutputStream(Path.of("bar"))) {
out.write(in.readAllBytes());
}
SOLUTION:
- Call the `close()` method inside a `finally` block.
- Using try-with-resources.
Closeable
and AutoCloseable
Only Closeable
or AutoCloseable
objects can be used in the try
statement.
Most of the I/O classes we've talked about, including Stream
, Reader
, Writer
, InputStream
, and OuptutStream
, already implement the Closeable
interface, whose close()
method can throw an IOException
.
AutoCloseable.close()
does not throw IOException
.
Closeable
and AutoCloseable
are just regular Java interfaces, which means you can write your own implmentations and then use them in a try-with-resources
block!